<?php
/**
 * huhaiqin,2025.2.5
 * 游戏用户数据相关的服务层
 */
namespace Game\Service;
use Think\Model;

class GameUserService extends Model{
    /**
     * du 2025.2.14
     * 用户登录
     * param mixed $openid 平台开放ID
     * Summary of user_login
     * @return mixed
     */
    public function user_login($openid, $unionid, $client = 'default', $info = null){
        $user = D('GameUser')->_get_game_user_by_openid($openid, 'id, status, role, task, limit, activity');
        $uid = $user['id'];
        if(!$uid){
            //用户不存在，创建用户
            $user = [
                'openid' => $openid,
                'unionid' => $unionid,
                // 这里写一下哪里登录的
                'client' => $client,
                'tel' => $info['tel'],
                'nickname' => $info['nickname'],
                'avatar_url' => $info['avatar_url'],
            ]; 
            $uid = D('GameUser')->_add_game_user($user);
            $role = C('DEFAULT_USER_INFO')['role'];
        }
        else{
            if(!$user['status']){
                return ['status' => 0,'msg' => '用户状态异常'];
            }
            if($user['is_del']){
                return ['status' => 0,'msg' => '用户被永久封禁']; 
            }
            // 查看有没有新的活动
            $user_activity = $user['activity'];
            // 获取当前进行的活动列表
            $activity_list = _get_activity_list();
            foreach($activity_list as $k => $v){
                // 增加新活动
               if(!$user_activity[$k]){
                    // 新活动，设置领奖励
                    $user_activity[$k] = [
                        'status' => 1, // 0-未完成，1-已完成
                        'progress' => 1, // 进度
                        'update_time' => time(), // 更新时间 
                    ];
                } 
            }
            $user['activity'] = $user_activity;
            $user['id'] = $uid;
            // $user['nickname'] = $info['nickname'];
            // $user['avatar_url'] = $info['avatar_url'];
            //用户存在，更新用户信息
            D('GameUser')->_edit_game_user_info($user);
            $role = $user['role'];
        }
        return ['status' => 1,'msg' => '登录成功', 'data' => ['uid' => $uid, 'role' => $role]];
    }

    /**
     * 初始化用户数据
     * @param mixed $uid
     * @return array

     */
    public function init_user_data($uid){
        $init_user_data = C('DEFAULT_USER_INFO');
        $init_user_data['id'] = $uid;
        $init_user_data['idol_id'] = null;
        $init_user_data['nickname'] = '';
        $init_user_data['challenge_id'] = null;
        $res = D('GameUser')->_edit_game_user_info($init_user_data);
        if(!$res){
            return ['status' => 0, 'msg' => '初始化失败'];
        }
        return ['status'=> 1,'msg'=> '初始化成功'];
    }

    /**
     * 修改用户信息
     * @param mixed $uid
     * @param array $info 要修改的信息
     * @param array $info nickname, avatar_url, 后续可以把avatar_id, avatar_frame_id等加上去
     * @return array
     */
    public function set_user_info($uid, $info){
        $user = D('GameUser')->_get_game_user_info($uid, 'nickname, avatar_url');
        if(!$user || $user['status'] == 0 || $user['is_del']){
            return ['status' => 0, 'msg' => '用户不存在'];
        }
        if($info['nickname']){
            $user['nickname'] = $info['nickname'];
        }
        if($info['avatar_url']){
            $user['avatar_url'] = $info['avatar_url'];
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0, 'msg' => '修改失败'];
        }
        return ['status' => 1, 'msg' => '修改成功'];
    }


    /**
     * du 2025.2.14
     * 获取完整用户信息
     * 比在MODEL中获取的信息增加一些等级计算等
     * 还有排序
     * param mixed $uid 用户id
     * @return mixed
     */
    public function get_full_user_info($uid){
        $user_info = D('GameUser')->_get_game_user_info($uid);
        if(!$user_info || $user_info['status'] == 0 || $user_info['is_del']){
            return ['status' => 0, 'msg' => '用户不存在'];
        }
        if(!$user_info['status']){
            return ['status' => 0,'msg' => '用户被禁用'];
        }
        if($user_info['is_del']){
            return ['status' => 0,'msg' => '用户已删除'];
        }
        _get_exchange_reward_list_by_backpack($user_info['backpack']);
        // 计算等级 _get_level_by_exp()函数
        $user_info['level'] = _get_level_by_exp($user_info['exp']);
        // 整理背包内容
        $user_info['currency'] = [];
        $user_info['skin'] = [];
        foreach($user_info['backpack'] as $key => $value){
            $item_group = _get_item_table()->get($key)->primeGroup;
            if($item_group == 1){
                // 货币单独存放
                $user_info['currency'][$key] = $value;
                unset($user_info['backpack'][$key]);
            }elseif($item_group == 4){
                // 皮肤单独存放
                $user_info['skin'][$key] = $value;
                unset($user_info['backpack'][$key]); 
            }elseif(!$value){
                // 剩余背包内数量为0的不显示
                unset($user_info['backpack'][$key]);
            }
        }
        // 处理章节关卡的情况
        $latest_stage = _get_latest_stage_id($user_info['stage']);
        $next_stage = _get_next_stage($latest_stage);
        $user_info['stage_id'] = $next_stage;
        // 不是最后一关，且下一关卡没有信息
        if($latest_stage !== $next_stage && !$user_info['stage'][$next_stage]){
            $user_info['stage'][$next_stage] = [
                'status' => 0,
                'record' => 0
            ];
        }
        // 单独处理徽章兑换活动的状态
        // foreach(_get_activity_list() as $k => $v){
        //     if($v['type'] == 'exchange'){
        //         $user_info['activity'][$k]['status'] = 1;
        //         foreach($v['reward'] as $k2 => $v2){
        //             if($user_info['backpack'][$k2] < $v2){
        //                 $user_info['activity'][$k]['status'] = 2; // 材料不足，无法兑换
        //                 break;
        //             }
        //         }
        //     }
        // }
        // 计算羁绊等级 _get_idol_level_by_favorability()函数
        foreach($user_info['idol'] as $key => $value){
            if($value){
                $idol_level = _get_idol_level_by_favorability($value['favorability']);
                $user_info['idol'][$key]['idol_level'] = $idol_level;
                for($i = 1; $i <= 5; $i++){
                    if($value['reward'][$i]){
                        continue;
                    }
                    elseif($idol_level >= $i){
                        $user_info['idol'][$key]['reward'][$i] = 1; 
                    }
                    else{
                        $user_info['idol'][$key]['reward'][$i] = -1;
                    }
                }
                ksort($user_info['idol'][$key]['reward']);
            }
        }
        // 增加M每天的todolist
        $user_info['todo_list'] = [

        ];
        return ['status' => 1, 'msg' => '获取成功', 'data' => $user_info];
    }

    /**
     * 2025.2.14
     * 更新引导
     */
    function update_guide_info($uid, $guide_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'guide');
        $user['guide'][$guide_id] = 1;
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '更新失败'];
        }
        return [ 'status' => 1,'msg' => '更新成功' ];
    }

    /**
     * du 2025.2.14
     * 商城购买物品
     * param mixed $uid 用户id
     * param mixed $product_id 物品id
     */
    public function buy_product($uid, $product_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack');
        if(!_check_user_limit($user)){
            return ['status' => 0,'msg' => '购买次数已达上限'];
        }
        $product = _get_config_table()->getTbProduct()->get($product_id);
        // 先计算消费
        $cost = $product->cost;
        if($cost){
            if($user['backpack'][$cost[0]] < $cost[1]){
                return ['status' => 0,'msg' => _get_item_table()->get($cost[0])->name . '不足'];
            }

            // 扣款
            $user['backpack'][$cost[0]] -= $cost[1];
        }
        // 判断商品类型 1-固定 2-抽取
        // 判断是否随机
        $item_list = [];
        if($product->isRandom){
            // 随机抽取暂时用这个代替
            $item_list = _get_item_by_product_id($product_id);
        }
        else{
            $item_res = $product->itemList;
            foreach($item_res as $v){
                $item_list[$v[0]] = $v[1]; 
            }
        }
        foreach($item_list as $k => $v){
            if(!$user['backpack'][$k]){
                $user['backpack'][$k] = $v;
            }else{
                $user['backpack'][$k] += $v;
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '购买失败'];
        }
        return ['status' => 1,'msg' => '购买成功', 'data' => ['item_list' => $item_list] ];
    }

    /**
     * du 2025.2.14
     * 激活皮肤
     * param mixed $uid 用户id
     * param mixed $skin_id 皮肤id
     * Summary of active_skin
     * @return mixed
     */
    public function activate_skin($uid, $skin_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'skin_id, pet_id, backpack');
        if(!$user['backpack'][$skin_id]){
            return ['status' => 0,'msg' => '皮肤未解锁'];
        }
        $skin = _get_item_table()->get($skin_id);
        // 判断是皮肤还是随从
        $skin_type_map = [
            1 => 'skin',
            2 =>'pet'
        ];
        $skin_type = $skin_type_map[$skin->secondaryGroup];
        if($user[$skin_type . '_id'] == $skin_id){
            return ['status' => 0,'msg' => '皮肤已激活'];
        }
        $user[$skin_type . '_id'] = $skin_id;
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '激活失败'];
        }
        return ['status' => 1,'msg' => '激活成功', 'data' => ['skin_id' => $skin_id ]];
    }

    /**
     * du 2025.2.14
     * 开始游戏接口，处理游戏开始的逻辑，包括扣除体力等
     * param mixed $uid 用户id
     * param mixed $stage_id 关卡id
     * Summary of game_start
     * @return mixed
     */
    public function game_start($uid, $stage_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'exp, stage, energy_recover_timestamp, challenge_id');
        $stage = _get_config_table()->getTbStage()->get($stage_id);
        // 检查等级
        $require_level = $stage->requireLevel;
        $user_level = _get_level_by_exp($user['exp']);
        if($user_level < $require_level){
            return ['status' => 0,'msg' => '等级不足，无法开始游戏'];
        }
        // 记录玩家上一次的无尽模式，且不是9000的试玩关卡
        if($stage->stageType == 2 && $stage_id != 9000){
            $user['challenge_id'] = $stage_id;
        }
        // 查看是否需要体力
        if(!$stage->costEnergy){
            $res = D('GameUser')->_edit_game_user_info($user);
            if(!$res){
                return ['status' => 0,'msg' => '开启游戏失败'];
            }
            return ['status' => 1,'msg' => '开始游戏成功', 'data' => ['stage_id' => $stage_id ]];
        }
        // 根据配置表读取全局配置
        $_full_energy = _get_config_table()->getTbStageConfig()->getfullEnergy();
        $_recover_time = _get_config_table()->getTbStageConfig()->getenergyRecoverTime() * 60;
        $energy_cost = $stage->costEnergy;
        // 判定是否有体力
        // 每30分钟恢复1点体力，体力恢复时间点比先在时间晚30分钟，则表示少一点体力
        if($user['energy_recover_timestamp'] > ( time() + ($_full_energy - $energy_cost) * $_recover_time ) ){
            return ['status' => 0,'msg' => '体力已用完，请补充体力后游戏'];
        } 
        // 扣除体力
        // 如果体力值满，则为现在时间往后，如果没满，则是恢复时间往后
        $user['energy_recover_timestamp'] = max(time() + $energy_cost * $_recover_time, $user['energy_recover_timestamp'] + $energy_cost * $_recover_time);
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '扣除体力失败'];
        }
        return ['status' => 1,'msg' => '开始游戏成功', 'data' => ['stage_id' => $stage_id, 'energy' => ( $_full_energy - ($user['energy_recover_timestamp'] - time()) / $_recover_time ) ]];
    }

    /**
     * du 2025.2.14
     * 结束结算接口，处理游戏结束的逻辑，包括奖励，跑动距离，是否完成任务等等
     * param mixed $uid 用户id
     * param mixed $stage_id 关卡id
     * param mixed $result 是否通关
     * param mixed $distance 跑动距离
     * param mixed $bonus 积分
     * Summary of game_end
     * @return mixed
     * 
     */
    public function game_end($uid, $stage_id, $result, $distance, $bonus = 0){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack, stage, distance, exp, idol_id, idol');
        $stage = _get_config_table()->getTbStage()->get($stage_id);
        // 累计跑动距离
        $user['distance'] = $user['distance'] + $distance;
        // 这里处理剧情模式的逻辑
        // 只记录状态
        if($stage->stageType == 1){
            // 如果关卡信息为空
            if(!$user['stage'][$stage_id]){
                $user['stage'][$stage_id] = [
                    'status' => 0,
                ];
            }
            // 通关后的逻辑
            if($result == 'success'){
                // 如果是首次通关，修改状态并解锁下一关卡
                if(!$user['stage'][$stage_id]['status']){
                    $user['stage'][$stage_id]['status'] = 1; // 0-未通关，1-已通关，2-已领取
                    // 剧情模式，解锁下一关卡，暂时不放在这里处理，去前端处理
                    // $next_stage = _get_next_stage($stage_id);
                    // // 如果不是最后一关，创建下一关的基础信息
                    // if($next_stage != $stage_id && !$user['stage'][$next_stage]){
                    //     $user['stage'][$next_stage] = [
                    //         'status' => 0,
                    //     ];
                    // }
                }
                // 发放奖励
                $reward_item_list = _get_reward_by_stage($stage_id);
                foreach($reward_item_list as $k => $v){
                    if($user['backpack'][$k] > 0 ){
                        $user['backpack'][$k] += $v;
                    }else{
                        $user['backpack'][$k] = $v;
                    }
                }

            }
        }
        // 这里记录挑战模式的逻辑
        // 只记录最长距离和挑战次数
        else if($stage->stageType == 2){
            if(!$user['stage'][$stage_id]){
                $user['stage'][$stage_id] = [
                    'record' => 0,
                    'times' => 0,
                ];
            }
            // 次数加一
            $user['stage'][$stage_id]['times'] ++;
            // 记录最佳距离
            if($user['stage'][$stage_id]['record'] < $distance){
                $user['stage'][$stage_id]['record'] = $distance;
            }
            // 这里应该是根据distance来获取奖励
            $collect_rate = _get_collect_level_by_backpack($user['backpack']);
            $favorability_rate = intval(_get_idol_level_by_favorability($user['idol'][$user['idol_id']]['favorability'])) / 10;
            $reward_rate = $collect_rate + $favorability_rate + 1;
            $reward_item_list = _get_reward_by_distance($stage_id, $distance, $reward_rate);
            // 这里用缓存记录奖励列表，用于判断领取额外奖励，5分钟过期
            $reward_token = 'parkour_' . $uid . uniqid();
            _set_reward_cache($reward_token, $reward_item_list);
            foreach($reward_item_list as $k => $v){
                if($user['backpack'][$k] > 0 ){
                    $user['backpack'][$k] += $v;
                }else{
                    $user['backpack'][$k] = $v;
                }
            }
        }
        // 挑战模式一定有升级奖励，主线模式通关了才有奖励升级
        if($stage->stageType == 2 || $result == 'success'){
            $upgrade_item_list = [];
            $upgrade_type_map = [
                2 =>'exp', // 经验值
                3 =>'favorability', // 亲密度
                4 =>'support', // 助力值
            ];
            // 升级奖励类型 1-经验值 2-亲密度 3-助力值
            $upgrade_res = $stage->upgrade;
            foreach($upgrade_res as $k => $v){
                $_item_id = $v[0];
                $_item_num = $v[1];
                $_item_type = $upgrade_type_map[_get_item_table()->get($_item_id)->secondaryGroup];
                if($_item_type == 'exp'){
                    $user['exp'] += $_item_num; 
                }
                if($_item_type == 'favorability'){
                    $user['idol'][$user['idol_id']]['favorability'] += $_item_num; 
                }
                if($_item_type == 'support'){
                    $user['idol'][$user['idol_id']]['support'] += $_item_num; 
                }
                $upgrade_item_list[$_item_id] = $_item_num;
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '游戏结算失败'];
        }
        return ['status' => 1,'msg' => '游戏结算成功', 'data' => ['stage_id' => $stage_id, 'reward_item_list' => $reward_item_list, 'upgrade_item_list' => $upgrade_item_list, 'reward_token' => $reward_token, 'collect_rate' => $collect_rate, 'favorability_rate' => $favorability_rate] ];
    }

    /**
     * 领取关卡内奖励（剧情模式，无尽模式，区分是否看广告加倍）
     * du 2025.2.14
     * param mixed $uid 用户id
     * param mixed $stage_id 关卡id
     * Summary of claim_stage_reward
     * @return mixed 
     */
    function claim_extra_reward($uid, $reward_token, $rate = 1){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack');
        // 从缓存中获取奖励列表，并删除缓存
        $reward_list = _get_reward_cache($reward_token);
        _set_reward_cache($reward_token, null);
        $reward_item_list = [];
        foreach($reward_list as $k => $v){
            $reward_item_list[$k] = $v * ($rate + 1);
            if($user['backpack'][$k] > 0){
                $user['backpack'][$k] += $v * $rate;
            }else{
                $user['backpack'][$k] = $v * $rate;
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '奖励领取失败'];
        }
        return ['status' => 1,'msg' => '奖励领取成功', 'data' => ['reward_item_list' => $reward_item_list ]];
    }

    /**
     * du 2025.2.14
     * 领取奖励
     * param mixed $uid 用户id
     * param mixed $stage_id 关卡id
     * Summary of claim_reward
     * @return mixed
     */
    public function claim_stage_reward($uid, $stage_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack, stage');
        // 判断有没有通关
        if($user['stage'][$stage_id]['status'] < 1){
            return ['status' => 0,'msg' => '未通关，无法领取奖励'];
        }
        // 判断是否领过奖励
        if($user['stage'][$stage_id]['status'] == 2){
            return ['status' => 0,'msg' => '奖励已领取'];
        }
        $stage = _get_config_table()->getTbStage()->get($stage_id);
        $reward_res = $stage->stageReward;
        if(!$reward_res){
            return ['status' => 0,'msg' => '奖励不存在'];
        }
        // 领取奖励
        $user['stage'][$stage_id]['status'] = 2;
        $reward_item_list = [];
        foreach($reward_res as $k => $v){
            $reward_item_list[$v[0]] = $v[1];
        }
        foreach($reward_item_list as $k => $v){
            if($user['backpack'][$k] > 0 ){
                $user['backpack'][$k] += $v; 
            } 
            else{
                $user['backpack'][$k] = $v; 
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '领取奖励失败'];
        }
        return ['status' => 1,'msg' => '领取奖励成功', 'data' => ['stage_id' => $stage_id,'reward_item_list' => $reward_item_list] ];
    }
    
    /**
     * du 2025.2.14
     * 增加玩家体力
     * param mixed $uid 用户id
     * param mixed $quantity 增加的体力数量
     * Summary of add_user_energy
     * @return mixed
     */
    public function recover_energy($uid, $quantity){
        $user = D('GameUser')->_get_game_user_info($uid, 'energy_recover_timestamp');
        if(!_check_user_limit($user)){
            return ['status' => 0,'msg' => '今日恢复次数已达上限'];
        }
        if($user['energy_recover_timestamp'] <= time()){
            return ['status' => 0,'msg' => '体力已满'];
        }
        // 根据配置表读取全局配置
        $_full_energy = _get_config_table()->getTbStageConfig()->getfullEnergy();
        $_recover_time = _get_config_table()->getTbStageConfig()->getenergyRecoverTime() * 60;
        $user['energy_recover_timestamp'] = max(time(), $user['energy_recover_timestamp'] - $quantity * $_recover_time);
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '增加体力失败'];
        }
        return ['status' => 1,'msg' => '增加体力成功', 'data' => ['energy' => ( $_full_energy - ($user['energy_recover_timestamp'] - time()) / $_recover_time ), 'energy_recover_timestamp' => $user['energy_recover_timestamp'] ]];
    }

    /**
     * du 2025.2.14
     * 解锁羁绊
     * param mixed $uid 用户id
     * param mixed $idol_id 羁绊id
     * Summary of unlock_idol
     * @return mixed
     */
    public function unlock_idol($uid, $idol_id){
        $idol_card_item_id = 10004;
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack, idol, idol_id');
        // 检查是否有羁绊卡
        if(!($user['backpack'][$idol_card_item_id] > 0)){
            return ['status' => 0,'msg' => '没有羁绊卡'];
        }
        // 检查是否有相同id的羁绊
        foreach($user['idol'] as $k => $v){
            if($k == $idol_id){
                return ['status' => 0,'msg' => '羁绊已解锁'];
            }
        }
        $user['idol'][$idol_id] = [
            'id' => $idol_id,
            'favorability' => 0,
            'support' => 0,
            'unlock_time' => time()
        ];
        $user['backpack'][$idol_card_item_id] --;
        // 如果用户没有解锁过羁绊，则激活当前羁绊
        if(!$user['idol_id']){
            $user['idol_id'] = $idol_id; 
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '解锁失败'];
        }
        return ['status' => 1,'msg' => '解锁成功', 'data' => ['idol' => $user['idol'][$idol_id]] ];
    }

    /**
     * du 2025.2.14
     * 激活羁绊
     * param mixed $uid 用户id
     * param mixed $idol_id 羁绊id
     * Summary of active_idol
     * @return mixed
     */
    public function activate_idol($uid, $idol_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'idol, idol_id'); 
        if(!$user['idol'][$idol_id]){
            return ['status' => 0,'msg' => '羁绊未解锁']; 
        }
        if($user['idol_id'] == $idol_id){
            return ['status' => 0,'msg' => '羁绊已激活']; 
        }
        $user['idol_id'] = $idol_id;
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '羁绊激活失败'];
        }
        return ['status' => 1,'msg' => '激活成功', 'data' => ['idol_id' => $idol_id] ];
    }

    /**
     * du 2025.2.14
     * 助力羁绊
     * param mixed $uid 用户id
     * param mixed $item_id 物品id
     * param mixed $quantity 数量
     * Summary of support_idol
     * @return mixed
     */
    public function support_idol($uid, $item_id, $quantity){
        $user = D('GameUser')->_get_game_user_info($uid, 'idol, idol_id, backpack');
        if(!$user['idol_id']){
            return ['status' => 0,'msg' => '未激活羁绊'];
        }
        if($user['backpack'][$item_id] < $quantity){
            return ['status' => 0,'msg' => '物品不足'];
        }
        $item_effect = _get_config_table()->getTbItemUse()->get($item_id)->params['support']->value;
        $idol = _get_config_table()->getTbIdol()->get($user['idol_id']);
        // 判断加成
        // 还有根据收藏等级、羁绊等级的加成
        if($idol->specialItem == $item_id){
            $item_effect *= 2; 
        }
        $total_jifen = $quantity * $item_effect;
        $user['idol'][$user['idol_id']]['support'] += $total_jifen;
        // 这里记录
        $jifen_res = D('GameUserJifen', 'Service')->support_idol($uid, $user['idol_id'], $total_jifen);
        // 处理排行榜逻辑
        // 更新日榜
        // D('GameSupportRank')->update_user_support($uid, $user['idol_id'], $total_jifen, 'day');
        // 更新周榜
        D('GameSupportRank')->update_user_support($uid, $user['idol_id'], $total_jifen, 'week');
        // 获取排行榜结果
        // $week_rank_list = D('GameSupportRank')->get_idol_user_rank_list($user['idol_id'], 'day', 100);
        // 还有一个羁绊助力总值
        $user['backpack'][$item_id] -= $quantity;
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '助力失败'];
        }
        return ['status' => 1,'msg' => '助力成功', 'data' => ['idol' => $user['idol'][$user['idol_id']]] ]; 
    }

    /**
     * du 2025.2.14
     * 领取羁绊等级奖励
     * param mixed $uid 用户id
     * param mixed $idol_level 物品id
     * param mixed $quantity 数量
     * Summary of claim_idol_reward
     * @return mixed 
     */
    public function claim_idol_reward($uid, $level){
        $user = D('GameUser')->_get_game_user_info($uid, 'idol, idol_id, backpack');
        if(!$user['idol_id']){
            return ['status' => 0,'msg' => '未激活羁绊'];
        }
        $idol_id = $user['idol_id'];
        $idol_info = $user['idol'][$idol_id];
        // 0-不可领取，1-可领取，2-已领取
        if($idol_info['reward'][$level] == 2){
            return ['status' => 0,'msg' => '奖励已领取'];
        }
        $idol_level = _get_idol_level_by_favorability($idol_info['favorability']);
        if($idol_level < $level){
            return ['status' => 0,'msg' => '未达到等级'];
        }
        $user['idol'][$idol_id]['reward'][$level] = 2;
        $reward_res = _get_config_table()->getTbIdol()->get($idol_id)->reward[$level - 1];
        $reward_item_list = [];
        $reward_item_list[$reward_res[0]] = $reward_res[1];
        if($user['backpack'][$reward_res[0]] > 0 ){
            $user['backpack'][$reward_res[0]] += $reward_res[1];  
        }
        else{
            $user['backpack'][$reward_res[0]] = $reward_res[1]; 
        } 
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '领取奖励失败'];
        }
        return ['status' => 1,'msg' => '领取奖励成功', 'data' => ['reward_item_list' => $reward_item_list] ];
    }

    /**
     * 领取排行榜奖励，可以看广告领取额外奖励
     * param mixed $uid 用户id
     * Summary of claim_rank_reward
     * @return mixed
     */
    public function claim_rank_reward($uid, $type, $mode){
        $user = D('GameUser')->_get_game_user_info($uid, 'idol, idol_id, backpack');
        if(!_check_user_limit($user)){
            return ['status' => 0,'msg' => '本周奖励已领取'];
        }
        // 根据排行榜计算奖励，暂时只有一个R币
        $reward_res = _get_reward_by_rank($uid, $type, $mode);
        $reward_item_list = [];
        foreach($reward_res as $v){
            $reward_item_list[$v[0]] = $v[1];
            if($user['backpack'][$v[0]] > 0 ){
                $user['backpack'][$v[0]] += $v[1];  
            }
            else{
                $user['backpack'][$v[0]] = $v[1]; 
            } 
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '领取奖励失败'];
        }
        return ['status' => 1,'msg' => '领取奖励成功', 'data' => ['reward_item_list' => $reward_item_list] ];
    }

    /**
     * du 2025.2.14
     * 辅助函数
     * 重置当日任务
     * param mixed $uid 用户id
     * Summary of reset_daily_task
     * @return mixed
     */
    public function reset_daily_task($uid){
        $daily_task = C('DAILY_TASK_LIST');
        $user = D('GameUser')->_get_game_user_info($uid, 'task');
        foreach($daily_task as $v){
            // status=0, update_time在今天之前，则重置, status=1, 不动, status=2, time在今天之前，重置
            // if(($user['task'][$v]['status'] != 1) && ($user['task'][$v]['update_time'] < strtotime('today midnight'))){
            if(true){
                $user['task'][$v]['status'] = 0;
                $user['task'][$v]['progress'] = 0;
                $user['task'][$v]['update_time'] = strtotime('today midnight');
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '重置任务失败'];
        }
        return ['status' => 1,'msg' => '重置任务成功', 'data' => ['task_list' => $user['task']] ];
    }

    /**
     * du 2025.2.14
     * 完成任务
     * param mixed $uid 用户id
     * param mixed $task_id 任务id
     * param mixed $progress 任务进度
     * Summary of complete_task
     * @return mixed
     * 
     */
    public function complete_task($uid, $task_id, $progress){
        // task包含以下内容：1.target 对应progress
        $task = _get_config_table()->getTbDailyTask()->get($task_id);
        $user = D('GameUser')->_get_game_user_info($uid, 'task');
        // 判断任务是否已完成，要联合清除今天之前的任务记录
        if($user['task'][$task_id]['status'] >= 1){
            return ['status' => 0,'msg' => '任务已完成'];
        }
        // 进行任务完成操作
        $user['task'][$task_id]['progress'] += $progress;
        // 判断是否达到任务目标
        if($user['task'][$task_id]['progress'] >= $task->totalProgress){
            $user['task'][$task_id]['status'] = 1;
            $user['task'][$task_id]['progress'] = $task->totalProgress;
            $user['task'][$task_id]['update_time'] = time(); 
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '任务完成失败'];
        }
        return ['status' => 1,'msg' => '任务完成成功', 'data' => ['task_info' => $user['task'][$task_id]] ];
    }

    /**
     * du 2025.2.14
     * 领取正式版任务奖励
     * param mixed $uid 用户id
     * param mixed $task_id 任务id
     * Summary of claim_task_reward
     * @return mixed
     *
     */
    public function claim_task_reward($uid, $task_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack'); 
        if($user['task'][$task_id]['status'] == 0){
            return ['status' => 0,'msg' => '任务未完成']; 
        }
        if($user['task'][$task_id]['status'] == 2){
            return ['status' => 0,'msg' => '任务奖励已领取']; 
        }
        // 修改任务状态
        //status=2 表示已领取
        $user['task'][$task_id]['status'] = 2;
        $user['task'][$task_id]['update_time'] = time();
        // 根据背包情况计算奖励物品
        $reward_res = _get_config_table()->getTbDailyTask()->get($task_id)->reward;
        $reward_item_list = [];
        foreach($reward_res as $v){
            $reward_item_list[$v[0]] = $v[1];
            $user['backpack'][$v[0]] += $v[1];
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '领取任务奖励失败'];
        }
        return ['status' => 1, 'msg' => '领取任务奖励成功', 'data' => ['task' => $user['task'][$task_id], 'reward_item_list' => $reward_item_list] ];
    }

    /**
     * du 2025.2.14
     * 微信分享功能
     * 两种逻辑，主要是考虑怎么领取奖励
     * 如果放在任务列表里，那就是通过claim_task_reward领取奖励，这里空edit一下就行
     * 如果不放在任务列表里，就要在请求wechat_share的时候把奖励领掉，用一条limit来记录
     * 这里处理一下领取奖励的过程
     */
    public function claim_share_reward($uid) {
        // 微信分享任务的TASK_ID = 20001
        $task_id = 20001;
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack');
        if($user['task'][$task_id]['status'] == 2){
            return ['status' => 0,'msg' => '分享奖励已领取'];
        }
        // 方案一 edit一下，更改任务状态，玩家可以在游戏内领取奖励
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status'=> 0,'msg'=> '领取分享奖励失败'];
        }
        return ['status'=> 1, 'msg'=> '分享成功'];
        // 方案二 直接领取奖励
        // 修改任务状态
        //status=2 表示已领取
        $user['task'][$task_id]['status'] = 2;
        $user['task'][$task_id]['update_time'] = time();
        // 根据背包情况计算奖励物品
        $reward_item_list = [];
        $task_reward = _get_config_table()->getTbDailyTask()->get($task_id)->reward;
        foreach( $task_reward as $v ){
            $reward_item_list[$v[0]] = $v[1];
            if($user['backpack'][$v[0]]){
                $user['backpack'][$v[0]] += $v[1];
            }else{
                $user['backpack'][$v[0]] = $v[1];
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '领取分享奖励失败'];
        }
        return ['status' => 1, 'msg' => '领取分享奖励成功', 'data' => ['task' => $user['task'][$task_id], 'reward_item_list' => $reward_item_list] ];

    }

    /**
     * 领取福利码奖励
     * @param mixed $uid
     * @param mixed $profit_code
     * @return mixed
     */
    public function claim_code_reward($uid, $code_reward_id) {
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack');
        $code_reward = _get_config_table()->getTbCodeReward()->get($code_reward_id);
        if(!$code_reward || $code_reward->status != 1){
            return ['status' => 0,'msg' => '福利码不存在'];
        }
        // 检查是否已领取
        $check_map = [
            'uid' => $uid
        ];
        // 如果是同类型的只能领取一次，直接找TYPE是否存在即可
        if($code_reward->typeUnique){
            $check_map['type'] = $code_reward->type;
        }
        // 否则就是找ID是否存在
        else{
            $check_map['code_reward_id'] = $code_reward->id;
        }
        $is_claimed = M('GameUserCodeReward')->where($check_map)->find();
        // 检查是否已领取
        if($is_claimed){
            // 存个缓存，避免多次查询
            S('code_reward_' . $uid . '_' . $code_reward->id, true, 3600);
            return ['status' => 0,'msg' => '福利码已领取'];
        }
        // 领取奖励
        $reward_item_list = [];
        foreach($code_reward->reward as $v){
            $reward_item_list[$v[0]] = $v[1];
            if($user['backpack'][$v[0]]){
                $user['backpack'][$v[0]] += $v[1];
            }else{
                $user['backpack'][$v[0]] = $v[1];
            }
        }
        $res = D('GameUser')->_edit_game_user_info($user);
        if(!$res){
            return ['status' => 0,'msg' => '领取福利码奖励失败'];
        }
        // 记录领取记录
        $post = [
            'uid' => $uid,
            'code_reward_id' => $code_reward->id,
            'type' => $code_reward->type,
            'status' => 1,
            'key' => $code_reward->key,
            'update_time' => time(),
        ];
        $res = M('GameUserCodeReward')->add($post);
        // 缓存记录，避免多次查询
        S('code_reward_' . $uid . '_' . $code_reward->id, true, 3600);
        return ['status' => 1, 'msg' => '领取福利码奖励成功', 'data' => ['reward_item_list' => $reward_item_list]];
    }

    /*********************************************** 抢鲜版相关 **********************************************/
    
    /**
     * du 2025.2.14
     * 结束结算接口，处理游戏结束的逻辑，包括奖励，跑动距离，是否完成任务等等
     * param mixed $uid 用户id
     * param mixed $stage_id 关卡id
     * param mixed $result 是否通关
     * param mixed $distance 跑动距离
     * Summary of game_end
     * @return mixed
     * 
     */
    public function trial_game_end($uid, $stage_id, $result, $distance){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack, stage, distance, task');
        // 累计跑动距离
        $post['distance'] = $user['distance'] + $distance;
        $post['task'] = $user['task'];
        // 判定当日任务，进行一次跑酷的任务id=10003
        if($user['task'][10003]['status'] == 0){
            $post['task'][10003]['status'] = 1; 
            $post['task'][10003]['progress'] = 1;
            $post['task'][10003]['update_time'] = time();
        }
        $post['stage'] = $user['stage'];
        // 记录最佳距离
        if($user['stage'][$stage_id]['record'] < $distance){
            $post['stage'][$stage_id]['record'] = $distance;
        }
        // 记录是否通关
        if(!$user['stage'][$stage_id]['status'] && $result == 'success'){
            $post['stage'][$stage_id]['status'] = 1; // 0-未通关，1-已通关，2-已领取
        }
        $reward_item_list = [];
        // 计算奖励，失败玩家不给奖励
        /*
        if($result == 'success'){
            // 记录关卡成功
            $post['stage'][$stage_id]['success'] = 1;
            // 根据玩家背包计算奖励规则，对应不同爆率，单独拎个函数，领任务物品也可以用
            $reward_item_list = _get_reward_list_by_backpack($user['backpack']); 
            $post['backpack'] = $user['backpack'];
            foreach($reward_item_list as $k => $v){
                if($post['backpack'][$k] > 0 ){
                    $post['backpack'][$k] += $v;
                }else{
                    $post['backpack'][$k] = $v;
                }
            }
        }
        */
        $post['id'] = $uid;
        $res = D('GameUser')->_edit_game_user_info($post);
        if(!$res){
            return ['status' => 0,'msg' => '游戏结算失败'];
        }
        return ['status' => 1,'msg' => '游戏结算成功', 'data' => ['stage_id' => $stage_id, 'reward_item_list' => $reward_item_list] ];
    }

    /**
     * du 2025.2.14
     * 领取抢鲜版任务奖励
     * param mixed $uid 用户id
     * param mixed $task_id 任务id
     * Summary of claim_task_reward
     * @return mixed
     *
     */
    public function claim_trial_task_reward($uid, $task_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'task, backpack'); 
        if($user['task'][$task_id]['status'] == 0){
            return ['status' => 0,'msg' => '任务未完成']; 
        }
        if($user['task'][$task_id]['status'] == 2){
            return ['status' => 0,'msg' => '任务奖励已领取']; 
        }
        // 修改任务状态
        $post['task'] = $user['task'];
        //status=2 表示已领取
        $post['task'][$task_id]['status'] = 2;
        $post['task'][$task_id]['update_time'] = time();
        // 根据背包情况计算奖励物品
        $reward_item_list = _get_reward_list_by_backpack($user['backpack']);
        $post['backpack'] = $user['backpack'];
        foreach($reward_item_list as $k => $v){
            $post['backpack'][$k] += $v;
        }
        $post['id'] = $uid;
        $res = D('GameUser')->_edit_game_user_info($post);
        if(!$res){
            return ['status' => 0,'msg' => '领取任务奖励失败'];
        }
        return ['status' => 1, 'msg' => '领取任务奖励成功', 'data' => ['task' => $post['task'][$task_id], 'reward_item_list' => $reward_item_list] ];
    }

    /**
     * du 2025.2.14
     * 完成活动任务
     * param mixed $uid 用户id
     * param mixed $activity_id 活动id
     * param mixed $progress 任务进度
     * Summary of complete_activity
     * @return mixed
     * 
     */
    public function complete_activity($uid, $activity_id, $progress){
        // task包含以下内容：1.target 对应progress
        $activity = _get_activity_list()[$activity_id];
        $user = D('GameUser')->_get_game_user_info($uid, 'activity');
        // 判断活动任务是否已完成
        if($user['activity'][$activity_id]['status'] >= 1){
            return ['status' => 0,'msg' => '活动已完成'];
        }
        // 进行任务完成操作
        $post['activity'] = $user['activity'];
        $post['activity'][$activity_id]['progress'] += $progress;
        // 判断是否达到任务目标
        if($post['activity'][$activity_id]['progress'] >= $activity['target']){
            $post['activity'][$activity_id]['status'] = 1; 
        } 
        $post['id'] = $uid;
        $res = D('GameUser')->_edit_game_user_info($post);
        if(!$res){
            return ['status' => 0,'msg' => '活动完成失败'];
        }
        return ['status' => 1,'msg' => '活动完成成功', 'data' => ['activity_info' => $post['activity'][$activity_id]] ];
    }

    /**
     * du 2025.2.14
     * 领取活动奖励
     * param mixed $uid 用户id
     * param mixed $activity_id 活动id
     * Summary of claim_activity_reward
     * @return mixed
     *
     */
    public function claim_activity_reward($uid, $activity_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'activity, backpack');
        if($user['activity'][$activity_id]['status'] == 0){
            return ['status' => 0,'msg' => '活动未完成'];
        }
        if($user['activity'][$activity_id]['status'] == 2){
            return ['status' => 0,'msg' => '活动奖励已领取'];
        }
        // 修改活动状态
        $post['activity'] = $user['activity'];
        $post['activity'][$activity_id]['status'] = 2;
        $post['activity'][$activity_id]['update_time'] = time();
        // 根据背包情况计算奖励物品
        $reward_item_list = _get_activity_list()[$activity_id]['reward'];
        $post['backpack'] = $user['backpack']; 
        foreach($reward_item_list as $k => $v){
            $post['backpack'][$k] += $v; 
        }
        $post['id'] = $uid;
        $res = D('GameUser')->_edit_game_user_info($post);
        if(!$res){
            return ['status' => 0,'msg' => '领取活动奖励失败'];
        }
        return ['status' => 1,'msg' => '领取活动奖励成功', 'data' => ['activity' => $post['activity'][$activity_id],'reward_item_list' => $reward_item_list] ];
    }
        /**
     * du 2025.2.14
     * 兑换活动奖励
     * param mixed $uid 用户id
     * param mixed $activity_id 活动id
     * Summary of exchange_activity_reward
     * 理论上是要设置兑换次数的，但是目前没有设置
     * 不用判断状态，只看能不能兑换
     * @return mixed
     *
     */
    public function exchange_activity_reward($uid, $activity_id){
        $user = D('GameUser')->_get_game_user_info($uid, 'backpack');
        $activity = _get_activity_list()[$activity_id];
        // 用了活动表的reward记录当下所需要的item_id => quantity
        $exchange_item = $activity['reward'];
        $post['backpack'] = $user['backpack'];
        // 检查背包是否足够,并扣除相应的item
        foreach($exchange_item as $k => $v){
            if($user['backpack'][$k] < $v){
                return ['status' => 0,'msg' => '兑换失败，背包中物品数量不足']; 
            }
            $post['backpack'][$k] -= $v;
        }
        // 根据背包情况计算奖励物品，这里换一个算法出东西
        $reward_item_list = _get_exchange_reward_list_by_backpack($user['backpack']);

        foreach($reward_item_list as $k => $v){
            $post['backpack'][$k] += $v; 
        }
        $post['id'] = $uid;
        $res = D('GameUser')->_edit_game_user_info($post);
        if(!$res){
            return ['status' => 0,'msg' => '领取活动奖励失败'];
        }
        return ['status' => 1,'msg' => '领取活动奖励成功', 'data' => ['activity' => $post['activity'][$activity_id],'reward_item_list' => $reward_item_list] ];
    }
}